package org.deft.timer {
	import flash.events.EventDispatcher;
	import flash.utils.getTimer;

	/**
	 * 此类为计算时间提供了基本功能
	 * 如果想实现秒表的功能可以使用DStopWatch
	 *
	 */
	public final class DWatchItem extends EventDispatcher {

		/**
		 * 当与DStopWatch一起使用时，此id做为索引用
		 */
		private var id:int;

		public function getID():int {
			return id;
		}
		//开始时间
		private var startTime:Number;
		//缓存已经使用的时间,pause后再次开开始时
		private var cacheTime:Number = 0;

		/**
		 * 此计时器要完成的计时时间, 大于0为倒计时
		 * @return
		 *
		 */
		public function getNeedMillisecond():Number {
			return needMillisecond;
		}
		private var needMillisecond:Number = 0;

		/**
		 * 当前已经记录时间 返回millisecond
		 * @return
		 *
		 */
		public function getUsedMillisecond():Number {
			return usedMillisecond;
		}

		public function setUsedMillisecond(usedMillisecond:Number):void {
			this.cacheTime = usedMillisecond;
		}
		private var usedMillisecond:Number = 0;

		/**
		 * 是否停止计时
		 * @return
		 *
		 */
		public function getIsStoped():Boolean {
			return stoped;
		}
		private var stoped:Boolean = true;

		/**
		 * 剩余时间
		 * @return
		 *
		 */
		public function getResidualMillisecond():Number {
			var time:Number = needMillisecond - usedMillisecond;
			if (stoped) {
				return 0;
			}
			if (time < 0)
				return 0;
			return time;
		}

		/**
		 *是否暂停计时
		 */
		public function getIsPaused():Boolean {
			return paused;
		}
		private var paused:Boolean = true;

		/**
		 *
		 * @param id 当与DStopWatch一起使用时，此id做为索引用,由DStopWatch自动分配，其他情况下可能不需要
		 * @param needMillisecond 如果为0，则持续计时，如果是大于0的数为倒计时，不能为负数
		 *
		 */
		public function DWatchItem(id:int = 0, needMillisecond:Number = 0) {
			this.id = id;
			if (needMillisecond < 0)
				throw new Error("needMillisecond 不能为负数");
			this.needMillisecond = needMillisecond;
		}
		private static var startEvent:DStopWatchEvent = new DStopWatchEvent(DStopWatchEvent.START);
		private static var changeEvent:DStopWatchEvent = new DStopWatchEvent(DStopWatchEvent.CHANGE);
		private static var overEvent:DStopWatchEvent = new DStopWatchEvent(DStopWatchEvent.TIMER_OVER);
		private static var resetEvent:DStopWatchEvent = new DStopWatchEvent(DStopWatchEvent.RESET);
		private static var stopEvent:DStopWatchEvent = new DStopWatchEvent(DStopWatchEvent.STOP);
		private static var pauseEvent:DStopWatchEvent = new DStopWatchEvent(DStopWatchEvent.PAUSE);

		/**
		 *用于开始，或恢复pause
		 *
		 */
		public function start():void {
			if (stoped) {
				cacheTime = 0;
				usedMillisecond = 0;
			}
			paused = false;
			stoped = false;
			startTime = getTimer();
			dispatchEvent(startEvent);
		}

		public function reStart():void {
			stop();
			start();
		}

		/**
		 * 重置时间并停止现在的计时
		 * @param needMillisecond
		 *
		 */
		public function reset(needMillisecond:Number = 0):void {
			if (needMillisecond < 0)
				throw new Error("needMillisecond 不能为负数");
			this.needMillisecond = needMillisecond;
			stop();
			dispatchEvent(resetEvent);
		}

		public function stop():void {
			stoped = true;
			dispatchEvent(stopEvent);
		}

		public function pause():void {
			paused = true;
			cacheTime = usedMillisecond;
			dispatchEvent(pauseEvent);
		}

		/**
		 * 计算并更新时间 ,在调用
		 * @param overCallBack
		 * @return
		 *
		 */
		public function update():Number {
			if (paused || stoped)
				return usedMillisecond;
			//
			usedMillisecond = cacheTime + getTimer() - startTime;

			if (needMillisecond > 0 && usedMillisecond >= needMillisecond) {
				usedMillisecond = needMillisecond;
				stop();
			}

			dispatchEvent(changeEvent);
			if (stoped)
				dispatchEvent(overEvent);
			return usedMillisecond;
		}

		public function tenthseconds():uint {
			return (getTempTime() % 1000 / 100) >> 0;

		}

		public function seconds():uint {
			return (getTempTime() / 1000) % 60 >> 0;

		}

		public function minutes():uint {


			return (getTempTime() / 60000) % 60 >> 0;

		}

		public function hours():uint {
			return (getTempTime() / 3600000) >> 0;

		}

		private function getTempTime():uint {
			var tempTime:uint = 0;
			if (needMillisecond > 0)
				tempTime = getResidualMillisecond();
			else
				tempTime = usedMillisecond;
			return tempTime;
		}

		override public function toString():String {
			return "{DWatchItem:" + hours() + ":" + minutes() + ":" + seconds() + "." + tenthseconds() + " }";
		}
	}
}

